<template>
  <ElPopover
    :visible="popoverVisible"
    placement="bottom-start"
    trigger="click"
    :width="searchBoxWidth"
    :show-arrow="false">
    <template #reference>
      <ElButton @click="open">
        <i
          class="iconfont icon-sift"
          :style="{
            marginRight: '8px',
          }" />
        所有筛选
        <ElIcon
          :style="{
            marginLeft: '10px',
          }">
          <ArrowDown />
        </ElIcon>
      </ElButton>
    </template>
    <div
      ref="formRef"
      style="padding: 20px 4px;">
      <slot />
      <ElRow style=" display: flex; justify-content: flex-end">
        <div>
          <ElButton
            type="primary"
            @click="$emit('search')">
            查询
          </ElButton>
          <ElButton @click="$emit('reset')">
            重置
          </ElButton>
        </div>
      </ElRow>
    </div>
  </ElPopover>
  <slot name="search" />
  <slot
    name="action" />
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
defineProps({
  // 搜索框宽度
  searchBoxWidth: {
    type: Number,
    default: 200,
  },
})
defineEmits(['search', 'reset'])

// 引用表单元素
const formRef = ref(null)

// 控制 Popover 的显示与隐藏
const popoverVisible = ref(false)

/**
 * 判断元素是否为指定父元素的子元素或本身
 * @param element - 要检查的元素
 * @param parent - 父元素
 * @returns 如果是子元素或本身返回 true，否则返回 false
 */
function isPopoverChildComponent(element, parent) {
  if (!element || !(element instanceof HTMLElement) || !parent) {
    return false
  }
  // 选择器弹窗需要加 selectPopover 类名
  // 判断 selectPopover 类是否在当前元素中
  if (element.classList.contains('selectPopover')) {
    return true
  }
  if (element === parent) {
    return true
  }
  // 递归判断父元素
  return isPopoverChildComponent(element.parentElement, parent)
}

/**
 * 处理全局点击事件，用于关闭 Popover
 * @param event - 点击事件对象
 */
function handleGlobalClick(event) {
  if (popoverVisible.value && !isPopoverChildComponent(event.target, formRef.value)) {
    popoverVisible.value = false
  }
}

/**
 * 打开或关闭 Popover
 * @param e - 点击事件对象
 */
function open(e) {
  popoverVisible.value = !popoverVisible.value
  e.stopPropagation()
}

/**
 * 关闭 Popover
 */
function close() {
  popoverVisible.value = false
}

// 组件挂载时添加全局点击事件监听器
onMounted(() => {
  document.addEventListener('click', handleGlobalClick)
})

// 组件卸载时移除全局点击事件监听器
onUnmounted(() => {
  document.removeEventListener('click', handleGlobalClick)
})

defineExpose({
  close,
})
</script>

<style scoped lang="scss">
</style>
